// part1:C14:ex14.25.cpp
// class Date.
#include <iostream>
#include <fstream>
#include <istringstream>
class Date
{
public:
    Date();
    Date(int y, int m, int d)
    {
        year = y;
        month = m;
        day = d;
    }
    friend istream& operator>>(istream &is, Date &dt);
    friend bool operator==(const Date &dl, const Date &dr);
    friend bool operator!=(const Date &dl, const Date &dr);
    friend bool operator<(const Date &dl, const Date &dr);
    friend bool operator<=(const Date &dl, const Date &dr);
    friend bool operator>(const Date &dl, const Date &dr);
    friend bool operator>=(const Date &dl, const Date &dr);
    Date& operator=(const std::string &date);
private:
    int year, month, day;
};

istream& operator>>(istream &is, Date &dt)
{
    is >> dt.year >> dt.month >> dt.day;
    if (!is) 
    {
        dt = Date(0, 0, 0);    
    }
    return is;
}

bool operator==(const Date &dl, const Date &dr)
{
    return dl.year == dr.year && dl.month == dr.month &&
        dl.day == dr.day;
}

bool operator!=(const Date &dl, const Date &dr)
{
    return !(dl == dr);
}

bool operator<(const Date &dl, const Date &dr)
{
    return (dl.year < dr.year) ||
        (dl.year == dr.year && dl.month < dr.month) ||
        (dl.year == dr.year && dl.month == dr.month &&
            dl.day < dr.day);
}

bool operator<=(const Date &dl, const Date &dr)
{
    return (dl < dr) || (dl == dr);
}

bool operator>(const Date &dl, const Date &dr)
{
    return !(dl <= dr);
}

bool operator>=(const Date &dl, const Date &dr)
{
    return (dl > dr) || (dl == dr);
}

Date& Date::operator=(const std::string &date)
{
    // accept characters like "1970-1-1" 
    std::istringstream in(date);
    char ch1, ch2;
    in >> yaer >> ch1 >> month >> ch2 >> day;
    if (!in || ch1 != '-' || ch2 != '-')
    {
        throw std::invalid_argument("Bad date");
    }

    if (month < 1 || month > 12 || day < 1 || day > 31)
    {
        throw std::invalid_argument("Bad date");
    }
    return *this;
}